<template>
  <div class="balance">
    <v-data-table
      :headers="headers"
      :items="transactions"
      :options.sync="options"
      :page.sync="pager.page"
      :items-per-page.sync="pager.pageSize"
      :server-items-length="pager.total"
      :loading="loading"
      @update:page="handlePage"
      @update:items-per-page="handlePageSize"
    >
      <template v-slot:top>
        <v-card flat>
          <v-row no-gutters>
            <v-col>
              <v-card-text class="grey--text ml-3 pb-0">
                Balance
                <v-btn x-small icon @click="hideBalance = !hideBalance">
                  <v-icon>mdi-eye{{hideBalance?'-off':''}}</v-icon>
                </v-btn>
              </v-card-text>
              <v-card-title class="pt-2" style="align-items: flex-start">
                $
                <span class="display-3 font-weight-thin">
                  <countTo
                    v-show="!hideBalance"
                    ref="counter"
                    :startVal="countTo.start"
                    :endVal="countTo.end"
                    :duration="1500"
                    :decimals="2"
                  ></countTo>
                  <span v-show="hideBalance">---.--</span>
                </span>
              </v-card-title>
            </v-col>
            <v-col>
              <v-list>
                <v-list-item>
                  <v-spacer/>
                  <v-dialog persistent v-model="dialog" max-width="640px">
                    <template v-slot:activator="{ on }">
                      <v-btn
                        color="primary"
                        dark
                        v-on="on"
                      >Transfer</v-btn>
                    </template>
                    <v-card>
                      <v-card-title>
                        <span class="headline">Transfer</span>
                      </v-card-title>
                      <v-card-text>
                        <v-container>
                          <v-form ref="editForm" v-model="valid">
                            <v-row>
                              <v-text-field
                                v-model="editedItem.to"
                                label="Transfer to whom?"
                                @change="handleVerify"
                                :loading="verifying"
                                :rules="accountRules"
                              ></v-text-field>
                            </v-row>
                            <v-row>
                              <v-text-field
                                v-model="editedItem.amount"
                                label="Amount"
                                :rules="amountRules"
                              ></v-text-field>
                            </v-row>
                            <v-row>
                              <v-text-field
                                v-model="editedItem.remark"
                                label="Remark"
                              ></v-text-field>
                            </v-row>
                          </v-form>
                        </v-container>
                      </v-card-text>
                      <v-card-actions>
                        <v-spacer></v-spacer>
                        <v-btn color="blue darken-1" text @click="hideDialog">Cancel</v-btn>
                        <v-btn color="blue darken-1" text :disabled="!valid" :loading="loading" @click="handleSave">Transfer</v-btn>
                      </v-card-actions>
                    </v-card>
                  </v-dialog>
                </v-list-item>
                <v-list-item>
                  <v-select
                    :items="filterTypes"
                    label="Type"
                    v-model="filteredType"
                    @change="handleFilter"
                  ></v-select>
                  <v-menu
                    v-model="datePicker"
                    :close-on-content-click="false"
                    :nudge-right="40"
                    transition="scale-transition"
                    offset-y
                    min-width="290px"
                  >
                    <template v-slot:activator="{ on }">
                      <v-text-field
                        v-model="dateRangeText"
                        label="Date Range"
                        prepend-icon="mdi-calendar-range"
                        readonly
                        v-on="on"
                        class="ml-2"
                        :append-icon="dateRangeText?'mdi-close':''"
                        @click:append="clearDateRange"
                      ></v-text-field>
                    </template>
                    <v-date-picker
                      range no-title
                      v-model="dateRange"
                      @input="handleDateRangeChange"
                    ></v-date-picker>
                  </v-menu>
                </v-list-item>
              </v-list>
            </v-col>
          </v-row>
        </v-card>
      </template>
      <template v-slot:item.transactionDate="{item}">
        {{item.transactionDate | moment('YYYY-MM-DD HH:mm:ss')}}
      </template>
      <template v-slot:item.balance="{item}">
        {{hideBalance?'hidden':item.balance.toFixed(2)}}
      </template>
      <template v-slot:item.expense="{item}">
        {{item.expense?item.expense.toFixed(2):''}}
      </template>
      <template v-slot:item.income="{item}">
        {{item.income?item.income.toFixed(2):''}}
      </template>
    </v-data-table>
  </div>
</template>

<script>
import countTo from 'vue-count-to';
import {addTransaction, getTransactions} from "../../../api/transaction";
import {getCard} from "../../../api/card";

export default {
  name: 'balance',
  components: {countTo},
  data: () => ({
    editedItem: {
      id: null,
      to: null,
      amount: 0,
      remark: null,
    },
    headers: [
      {text: '#', value: 'id', sortable: false},
      {text: 'Type', value: 'transactionType', sortable: false},
      {text: 'Expense', value: 'expense', sortable: false},
      {text: 'Income', value: 'income', sortable: false},
      {text: 'Balance', value: 'balance', sortable: false},
      {text: 'Date', value: 'transactionDate', sortable: false},
      {text: 'Remark', value: 'remark', sortable: false},
    ],
    transactions: [],
    loading: false,
    verifying: false,
    verified: true,
    datePicker: false,
    pager: {
      page: 1,
      pageSize: 15,
      total: 1,
      totalPages: 1,
    },
    countTo: {
      start: 0,
      end: 0,
    },
    hideBalance: false,
    filterTypes: ['All', 'Income', 'Expense'],
    filteredType: 'All',
    dateRange: [],
    lastDateRange: [],
    options: {},
    valid: false,
    dialog: false,
  }),
  computed: {
    dateRangeText() {
      return this.dateRange.join(' ~ ');
    },
    card() {
      return this.$store.getters.card;
    },
    accountRules() {
      const rules = [
        v => !!v || 'Required',
        v => !!v && v.length === 16 || 'Must be 16 numbers long',
        v => !!v && /^\d+$/.test(v) || 'Must be a number'
      ];
      rules.push(v => v !== this.card.cardNo || 'You cannot transfer to yourself');
      rules.push(() => this.verified || 'Account is suspended or does not exist');
      return rules;
    },
    amountRules() {
      const rules = [
        v => !!v || v === 0 || 'Required',
        v => ~~v && ~~v > 0 || 'Amount must be greater than zero'
      ];
      rules.push(v => !!this.$store.getters.card.cardNo && ~~v <= this.$store.getters.card.balance || 'Insufficient balance');
      return rules;
    }
  },
  methods: {
    handleBalanceChanged() {
      const ret = this.$store.getters.card.balance;
      this.countTo.start = this.countTo.end;
      this.countTo.end = ret;
      this.$refs['counter'].reset();
    },
    clearDateRange() {
      this.dateRange = [];
      this.lastDateRange = [];
      this.handleDateRangeChange();
    },
    handleDateRangeChange() {
      if (this.dateRange.length === 2) {
        if (this.lastDateRange[0] !== this.dateRange[0] || this.lastDateRange[1] !== this.dateRange[1]) {
          this.lastDateRange[0] = this.dateRange[0];
          this.lastDateRange[1] = this.dateRange[1];
          this.loadTransactions();
        }
        this.datePicker = false;
      } else if (this.dateRange.length === 0) {
        this.loadTransactions();
      }
    },
    handleVerify() {
      const to = this.editedItem.to;
      if (to && to.length === 16) {
        this.verifying = true;
        getCard(to).subscribe(res => {
          if (res.data) {
            this.verified = res.data.status === 1;
          }
          else this.verified = false;
          this.verifying = false;
          this.$refs['editForm'].validate();
        }, err => {
          this.$toasted.error(err);
          this.verified = false;
          this.verifying = false;
        })
      }
    },
    handleFilter() {
      this.pager.page = 1;
      this.pager.total = 0;
      this.pager.totalPages = 0;
      this.loadTransactions();
    },
    handlePage(page) {
      this.pager.page = page;
      this.loadTransactions();
    },
    handlePageSize(size) {
      if (size === -1) {
        this.$toasted.error('Page size cannot be "All"');
        this.pager.pageSize = 15;
      } else {
        this.pager.pageSize = size;
        this.loadTransactions();
      }
    },
    resetItem() {
      Object.keys(this.editedItem).forEach(k => this.editedItem[k] = null);
      this.editedItem.amount = 0;
    },
    hideDialog() {
      this.$refs['editForm'].reset();
      this.dialog = false;
      this.resetItem();
    },
    handleSave() {
      this.handleAdd();
    },
    handleAdd() {
      if (!this.editedItem.id) {
        this.loading = true;
        addTransaction(this.editedItem.to, this.editedItem.amount, this.editedItem.remark).subscribe(res => {
          console.log(res);
          this.loading = false;
          if (!res) {
            this.$toasted.error('Credential is required');
          } else {
            this.hideDialog();
            if (res.data) {
              this.$toasted.info('Transfer successfully');
              this.loadTransactions();
              this.$store.dispatch('card/resume').then(() => this.handleBalanceChanged());
            } else {
              this.$toasted.error('No response');
            }
          }
        }, err => {
          if (err.response && err.response.data) {
            this.$toasted.error(err.response.data.message);
          } else this.$toasted.error(err);
          this.loading = false;
        })
      }
    },
    loadTransactions() {
      const {page, pageSize} = this.pager;
      const cardNo = this.$store.getters.card.cardNo;
      // console.log(cardNo);
      if (!cardNo) return;
      this.loading = true;
      getTransactions(page, pageSize, cardNo, this.filteredType, this.dateRange).subscribe(res => {
        // console.log(res);
        if (res.data) {
          const {current, data, pageSize, total, totalPages} = res.data;
          this.pager.pageSize = pageSize;
          this.pager.page = current;
          this.pager.total = total;
          this.pager.totalPages = totalPages;
          this.transactions = data;
        }
        this.loading = false;
      }, err => {
        console.log(err.response);
        this.$toasted.error(err);
        this.loading = false;
      })
    },
  },
  mounted() {
    this.$store.dispatch('card/resume').then(card => {
      if (card) {
        this.$nextTick(() => {
          this.handleBalanceChanged();
          this.loadTransactions();
        });
      } else {
        this.$router.push('/card');
      }
    }).catch(err => {
      this.$toasted.error(err.response.data.message);
      this.$router.push('/card');
    });
  }
};
</script>
